﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using LBSWebService.DataAccess;
using System.Collections.Generic;
using LBSWebService.BusinessLogic.Profile;
using LBSWebService.BusinessLogic.BusinessObjects;

namespace LBSWebService.BusinessLogic
{
    public static class DistanceCalculation
    {

        public static List<CurrentLocation> GetUsersInClose(Guid pUserId)
        {
            List<CurrentLocation> usersCurrentLocations = new List<CurrentLocation>();
            CurrentLocation usersLocation = LBSDataAccessLayer.GetCurrentLocation(pUserId);
            if (usersLocation != null)
            {
                List<CurrentLocation> allCurrentLocation = LBSDataAccessLayer.GetAllCurrentLocation(DateTime.Now.AddMinutes(-5));
                foreach (CurrentLocation aUsersLocation in allCurrentLocation)
                {
                    // No match for itself
                    if (aUsersLocation.UserId != pUserId)
                    {
                        if (CalcDistLatLong(usersLocation, aUsersLocation) < 2)
                        {
                            usersCurrentLocations.Add(aUsersLocation);
                        }
                    }
                }
            }
           
            return usersCurrentLocations;
        }


        enum DistanceUnits
        {
            StatuteMiles,
            NauticalMiles,
            Kilometers
        }

        public static double CalcDistLatLong(CurrentLocation pCurrLoc1, CurrentLocation pCurrLoc2)
        {
            return CalcDistLatLong(pCurrLoc1.Latitude, pCurrLoc1.Longitude, pCurrLoc2.Latitude, pCurrLoc2.Longitude);
        }

        /// <summary>
        /// Calculates the distance between two GPS points, in one of three formats (statute miles,
        /// nautical miles, or kilometers).
        /// </summary>
        /// <param name="lat1">latitude of the first point</param>
        /// <param name="lon1">longitude of the first point</param>
        /// <param name="lat2">latitude of the second point</param>
        /// <param name="lon2">longitude of the second point</param>
        /// <param name="units">DistanceUnits enum value</param>
        /// <returns>double</returns>
        public static double CalcDistLatLong(double lat1, double lon1, double lat2, double lon2)
        {
            ///Credits to 'The Math Forum' for the formula
            ///http://mathforum.org/library/drmath/view/51879.html 

            double degrad = Math.PI / 180;
            double a, c, R;
            R = 0;
            double dlon, dlat;

            //convert the degree values to radians before calculation
            lat1 = lat1 * degrad;
            lon1 = lon1 * degrad;
            lat2 = lat2 * degrad;
            lon2 = lon2 * degrad;

            dlon = lon2 - lon1;
            dlat = lat2 - lat1;

            a = Math.Pow(Math.Sin(dlat / 2), 2) + Math.Cos(lat1) * Math.Cos(lat2) * Math.Pow(Math.Sin(dlon / 2), 2);
            c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));

            //// R (Earth Radius) = 3956.0 mi = 3437.7 nm = 6367.0 km
            //switch (units)
            //{
            //    case DistanceUnits.StatuteMiles: // STATUTE MILES
            //        R = 3956.0;
            //        break;
            //    case DistanceUnits.NauticalMiles: // NAUTICAL 
            //        R = 3437.7;
            //        break;
            //    case DistanceUnits.Kilometers: // KILOMETERS 
            //        R = 6367.0;
            //        break;
            //}

            R = 6367.0;
            return (R * c);
        }


    }
}
